#ifndef MESSAGE_H
#define MESSAGE_H
#include "common.h"

enum PlayerUI {
    PLAYERUI_QUERY_PUSH,
    PLAYERUI_QUERY_PULL,
    PLAYERUI_QUERY_LOOK,
    PLAYERUI_QUERY_LIGHT,
    PLAYERUI_QUERY_PICKUP,
    PLAYERUI_QUERY_DROP,
    PLAYERUI_QUERY_WEAR,
    PLAYERUI_QUERY_WIELD,
    PLAYERUI_QUERY_REMOVE,
    PLAYERUI_QUERY_EAT,
    PLAYERUI_LOOK_DARK,
    PLAYERUI_PICKUP_DARK,
    PLAYERUI_BLOCKED_DARK,
    PLAYERUI_NOTHING_HERE,
    PLAYERUI_NOTHING_INVENTORY,
    PLAYERUI_NOTHING_FIRESOURCE,
    PLAYERUI_PICKUP_FAIL,
    PLAYERUI_PUSH_FAIL,
    PLAYERUI_PUSH_NOTHING,
    PLAYERUI_PULL_NOTHING,
    PLAYERUI_PULL_BLOCKED,
    PLAYERUI_FAIL_WEARING,
    PLAYERUI_FAIL_WIELDING,
    PLAYERUI_FAIL_UNWEARABLE,
    PLAYERUI_FAIL_UNWIELDABLE,
    PLAYERUI_FAIL_ALREADY_WORN,
    PLAYERUI_FAIL_ALREADY_WIELDED,
    PLAYERUI_FAIL_NEED_FREE_HAND,
    PLAYERUI_FAIL_NEED_BOTH_HANDS,
    PLAYERUI_FAIL_RING,
    PLAYERUI_FAIL_NECK,
    PLAYERUI_FAIL_HAND,
    PLAYERUI_FAIL_FEET,
    PLAYERUI_FAIL_HEAD,
    PLAYERUI_FAIL_BODY,
    PLAYERUI_FAIL_NOT_EQUIPPED
};

enum Unary {
    UNARY_FIRE_DESTROY_INSTANT,
    UNARY_FIRE_DESTROY_EVENTUAL,
    UNARY_FIRE_CATCH_FIRE_BRIGHT,
    UNARY_FIRE_CATCH_FIRE,
    UNARY_FIRE_SMOULDER,
    UNARY_FIRE_CHAR,
    UNARY_FIRE_GO_OUT
};

enum Binary {
    BINARY_SHOVE_FAIL,
    BINARY_DRAG_FAIL,
    BINARY_DRAG_SUCCEED,
    BINARY_PUSH_SUCCEED,
    BINARY_SHOVE_SUCCEED,
    BINARY_ITEM_DROP
};

enum Manipulation {
    MANIPULATION_WEAR,
    MANIPULATION_WIELD_MAIN,
    MANIPULATION_WIELD_FREE,
    MANIPULATION_WIELD_BOTH,
    MANIPULATION_UNWEAR,
    MANIPULATION_UNWIELD,
    MANIPULATION_EAT_RING,
    MANIPULATION_EAT_LEATHER,
    MANIPULATION_EAT_CHARRED_LEATHER,
    MANIPULATION_EAT_TORCH,
    MANIPULATION_EAT_MATCHES,
    MANIPULATION_EAT_OTHER,
    MANIPULATION_DRINK_OTHER
};

// Currently these match up, need to change TernarySwitch if they ever don't
enum Ternary {
    TERNARY_ALIGHT_FROM_BRAZIER,
    TERNARY_ALIGHT_FROM_BURNING_OBJECT,
    TERNARY_ALIGHT_FROM_MATCH
};
enum ManipulationWith {
    MANIPULATIONWITH_ALIGHT_FROM_BRAZIER,
    MANIPULATIONWITH_ALIGHT_FROM_BURNING_OBJECT,
    MANIPULATIONWITH_ALIGHT_FROM_MATCH
};

class MessageBank {
public:

    MessageBank( Game& game );

    // Player-specific UI message (only does anything if player is the player)
    std::string GetPlayerUI( uint m, Actor* player );
    // Something happens to an actor or item
    std::string GetUnary( uint m, Behaved* target );
    // Actor manipulates another actor (assumes source != target)
    std::string GetBinary( uint m, Actor* source, Actor* target );
    // Actor manipulates an item in its inventory (assumes source carries target)
    std::string GetManipulation( uint m, Actor* source, Item* target );
    // Actor manipulates another actor using an object
    // (assumes source carries with if with is an item)
    std::string GetTernary( uint m, Actor* source, Actor* target, Behaved* with );
    // Actor manipulates an item in its inventory using an object (assumes source carries target
    // and source carries with if with is an item)
    std::string GetManipulationWith( uint m, Actor* source, Item* target, Behaved* with );
    // Chooses between ternary and manipulationwith depending on type of target
    std::string GetTernarySwitch( uint m, Actor* source, Behaved* target, Behaved* with );

    void PlayerUI( uint m, Actor* player );
    void Unary( uint m, Behaved* target );
    void Binary( uint m, Actor* source, Actor* target );
    void Manipulation( uint m, Actor* source, Item* target );
    void Ternary( uint m, Actor* source, Actor* target, Behaved* with );
    void ManipulationWith( uint m, Actor* source, Item* target, Behaved* with );
    void TernarySwitch( uint m, Actor* source, Behaved* target, Behaved* with );

private:

    void Queue( const ustring& s );
    void Queue( const std::string& s );

    Game& _game;

};

#endif